package com.zd.bms.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zd.bms.bean.vo.req.BmsRoleReqListVo;
import com.zd.bms.bean.vo.req.RoleMenuTreeVoReqVo;
import com.zd.bms.bean.vo.resp.BmsResourceRespVo;
import com.zd.bms.bean.vo.resp.BmsRoleRespVo;
import com.zd.bms.bean.vo.resp.ZTreeResource;
import com.zd.bms.service.IBmsRoleService;
import com.zd.common.bean.model.BmsResource;
import com.zd.common.bean.model.BmsRole;
import com.zd.common.bean.model.BmsRoleResource;
import com.zd.common.bean.model.BmsUser;
import com.zd.common.common.enums.BmsRoleTypeEnum;
import com.zd.common.common.enums.BmsUserTypeEnum;
import com.zd.common.common.utils.LogUtils;
import com.zd.common.common.utils.StringUtils;
import com.zd.common.dao.BmsResourceDao;
import com.zd.common.dao.BmsRoleDao;
import com.zd.common.dao.BmsRoleResourceDao;
import com.zd.common.dao.BmsUserDao;
import com.zd.common.dao.common.BaseDao;
import com.zd.common.dao.common.FindRequestEntity;
import com.zd.common.dao.common.OrderEnum;
import com.zd.common.dao.common.Page;
import com.zd.common.dao.common.WhereEnum;
import com.zd.common.service.impl.BaseServiceImpl;

@Service
public class BmsRoleServiceImpl extends BaseServiceImpl<BmsRole> implements IBmsRoleService{
	
	@Autowired
	private BmsRoleDao bmsRoleDao;
	
	@Autowired
	private BmsResourceDao bmsResourceDao; 
	
	@Autowired
	private BmsRoleResourceDao bmsRoleResourceDao;
	
	@Autowired
	private BmsUserDao bmsUserDao;
	
	@Override
	public BaseDao<BmsRole> getBaseDao() {
		return bmsRoleDao;
	}

	@Override
	public Page<BmsRoleRespVo> findAllRole(BmsRoleReqListVo reqVo) throws Exception {
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addOrder("create_time", OrderEnum.DESC);
		findReq.setPage(reqVo.getPageNo(), reqVo.getPageSize());
		Page<BmsRole> bmsRolePage = page(findReq);
		Page<BmsRoleRespVo> bmsRoleRespVoPage = new Page<>();
		List<BmsRole> bmsRoleList = bmsRolePage.getList();
		List<BmsRoleRespVo> bmsRoleRespVoList = new ArrayList<>();
		if(bmsRoleList != null && bmsRoleList.size() >0){
			for (BmsRole bmsRole : bmsRoleList) {
				BmsRoleRespVo bmsRoleRespVo =new BmsRoleRespVo();
				bmsRoleRespVo.setBmsRoleRespVo(bmsRole);
				BmsUser bmsUser = bmsUserDao.get(bmsRole.getOperator());
				if(bmsUser !=null && !StringUtils.isBank(bmsUser.getEntNo())){
					bmsRoleRespVo.setOperatorName(bmsUser.getEntNo());
				}
				bmsRoleRespVoList.add(bmsRoleRespVo);
			}
		}
		bmsRoleRespVoPage.setList(bmsRoleRespVoList);
		bmsRoleRespVoPage.setPage(bmsRolePage.getPage());
		bmsRoleRespVoPage.setPageSize(bmsRolePage.getPageSize());
		bmsRoleRespVoPage.setTotalRow(bmsRolePage.getTotalRow());
		return bmsRoleRespVoPage;
	}

	@Override
	public boolean saveAndUpdateRole(RoleMenuTreeVoReqVo bmsRoleReqVo, BmsUser bmsUser) throws Exception {
		BmsRole bmsRole = new BmsRole();
		BeanUtils.copyProperties(bmsRoleReqVo, bmsRole);
		bmsRole.setOperator(bmsUser.getId());
		LogUtils.info(bmsRole.toString());
		if (bmsRole.getId() == null) {//为null新增的 insert
			bmsRole.setCreateTime(new Date());
			bmsRole.setUpdateTime(new Date());
			insert(bmsRole);
		} else {//有ID ，update
			bmsRole.setUpdateTime(new Date());
			update(bmsRole);
		}
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("role_id", WhereEnum.EQ, bmsRole.getId());
		bmsRoleResourceDao.delWhere(findReq.getWhereList());
		if(bmsRoleReqVo.getMenuTreeVoList() != null && bmsRoleReqVo.getMenuTreeVoList().size() > 0){
			for (Integer resourceId : bmsRoleReqVo.getMenuTreeVoList()) {
				insertRoleResource(resourceId, bmsRole, bmsUser);
			}
		}
		return true;
	}
	
	/**
	 * 将角色合权限关系保存
	 * @param menuTreeVo
	 * @param bmsRole
	 * @param bmsUser
	 * @throws Exception
	 */
	private void insertRoleResource(Integer resourceId, BmsRole bmsRole , BmsUser bmsUser)throws Exception{
		BmsRoleResource bmsRoleResource = new BmsRoleResource();
		bmsRoleResource.setRoleId(bmsRole.getId());
		bmsRoleResource.setResourceId(resourceId);
		bmsRoleResource.setOperator(bmsUser.getId());
		bmsRoleResource.setCreateTime(new Date());
		bmsRoleResource.setUpdateTime(new Date());
		bmsRoleResourceDao.insert(bmsRoleResource);
	}

	@Override
	public Map<String, Object> findRole(Integer id) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		BmsRole bmsRole = get(id);
		Set<ZTreeResource> roleZTreeResourceVo = new HashSet<>();
		if(bmsRole != null){
			roleZTreeResourceVo = findMenuTreeVo(bmsRole.getId());
		}
		Set<ZTreeResource> bmsZTreeResourceVo = findMenuTreeVo(null);
		roleZTreeResourceVo.addAll(bmsZTreeResourceVo);
		resultMap.put("bmsZTreeResourceVo", roleZTreeResourceVo);
		return resultMap;
	}
	
	/**
	 * 有角色id，就获取角色下所有的权限;    
	 * 角色id为null，就获取系统所有的权限
	 * @param roleId
	 * @return
	 * @throws Exception
	 */
	private Set<ZTreeResource> findMenuTreeVo(Integer roleId) throws Exception{
		Set<BmsResource> resourceSet = new HashSet<>();
		FindRequestEntity findReq = new FindRequestEntity();
		if (roleId == null) {
			List<BmsResource> bmsResourceList = bmsResourceDao.find(findReq);
			resourceSet = new HashSet<>(bmsResourceList);		
		}else {
			findReq.addWhere("role_id", WhereEnum.EQ, roleId);
			List<BmsRoleResource> roleResourceList = bmsRoleResourceDao.find(findReq);
			if (roleResourceList != null && roleResourceList.size() > 0) {
				for (BmsRoleResource roleResource : roleResourceList) {
					BmsResource resource = bmsResourceDao.get(roleResource.getResourceId());
					if (resource != null) {
						resourceSet.add(resource);
					}
				}
			}
		}
		List<BmsResource> resourceList = new ArrayList<>();
		resourceList.addAll(resourceSet);
		Collections.sort(resourceList);
		Set<ZTreeResource> zTreeResourceList = new HashSet<>();
		ZTreeResource otherZTreeResource = new ZTreeResource();
		otherZTreeResource.setName("其它");
		otherZTreeResource.setId(999999);
		otherZTreeResource.setpId(0);
		otherZTreeResource.setOpen(true);
		zTreeResourceList.add(otherZTreeResource);
		for (BmsResource bmsResource : resourceList) {
			ZTreeResource zTreeResource = new ZTreeResource();
			if(roleId !=null){
				zTreeResource.setChecked(true);
			}
			zTreeResource.setId(bmsResource.getId());
			zTreeResource.setResourceId(bmsResource.getId());
			if(bmsResource.getParentId() != null){
				zTreeResource.setpId(bmsResource.getParentId());
			}
			if(bmsResource.getLevel() == 0){
				zTreeResource.setpId(otherZTreeResource.getId());
			}
			if(bmsResource.getLevel() != 0 && bmsResource.getLevel() != 4){
				zTreeResource.setOpen(true);
				zTreeResource.setChild(false);
			}else {
				zTreeResource.setOpen(false);
				zTreeResource.setChild(true);
			}
			zTreeResource.setName(bmsResource.getName());
			zTreeResourceList.add(zTreeResource);
		}
		return zTreeResourceList;
	}

	@Override
	public List<BmsResourceRespVo> findAllResource() throws Exception {
		List<BmsResourceRespVo> resourceRespVoList = new ArrayList<>();
		FindRequestEntity findReq = new FindRequestEntity();
		List<BmsResource> bmsResourceList= bmsResourceDao.find(findReq);
		BmsResourceRespVo otherResourceRespVo = new BmsResourceRespVo();
		otherResourceRespVo.setName("其它");
		otherResourceRespVo.setId(999999);
		otherResourceRespVo.setpId(0);
		otherResourceRespVo.setLevel(1);
		resourceRespVoList.add(otherResourceRespVo);
		System.out.println(System.currentTimeMillis());
		for (BmsResource bmsResource : bmsResourceList) {
			BmsResourceRespVo bmsResourceRespVo = new BmsResourceRespVo();
			bmsResourceRespVo.setId(bmsResource.getId());
			bmsResourceRespVo.setLevel(bmsResource.getLevel());
			bmsResourceRespVo.setName(bmsResource.getName());
			bmsResourceRespVo.setUrlStr(bmsResource.getUrl());
			bmsResourceRespVo.setParentId(bmsResource.getParentId());
			bmsResourceRespVo.setpId(bmsResource.getParentId());
			if(bmsResource.getLevel() == 0){
				bmsResourceRespVo.setpId(otherResourceRespVo.getId());
			}
			resourceRespVoList.add(bmsResourceRespVo);
		}
		System.out.println(System.currentTimeMillis());
		return resourceRespVoList;
	}

	@Override
	public boolean addOrUpdateResourcet(BmsResource bmsResource, BmsUser bmsUser) throws Exception {
		if(bmsResource.getId() == null){
			
			//判断有没有父类，没有父类的为单独菜单，级别与父类id都为0
			BmsResource pBmsResource = bmsResourceDao.get(bmsResource.getParentId());
			if(pBmsResource != null){
				bmsResource.setLevel(pBmsResource.getLevel() + 1);
				bmsResource.setParentId(pBmsResource.getId());
			}else {
				bmsResource.setLevel(0);
				bmsResource.setParentId(0);
			}
			
			bmsResource.setOperator(bmsUser.getId());
			bmsResource.setCreateTime(new Date());
			bmsResource.setUpdateTime(new Date());
			
			bmsResourceDao.insert(bmsResource);
			return true;
		}else {
			BmsResource oldBmsResource = bmsResourceDao.get(bmsResource.getId());
			oldBmsResource.setName(bmsResource.getName());
			oldBmsResource.setUrl(bmsResource.getUrl());
			oldBmsResource.setUpdateTime(new Date());
			bmsResourceDao.update(oldBmsResource);
			return true;
		}
	}

	@Override
	public Map<String, Object> delResourcet(Integer id) throws Exception {
		delResourcetList(id);
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("result", true);
		return resultMap;
	}
	
	/**
	 * 查询是否有子菜单，有则递归查询子菜单是否有下级菜单，查完，不管有没有都删掉自己
	 * @param id
	 * @throws Exception
	 */
	private void delResourcetList(Integer id)throws Exception{
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("parent_id", WhereEnum.EQ, id);
		List<BmsResource> bmsResourceList = bmsResourceDao.find(findReq);
		if(bmsResourceList != null && bmsResourceList.size() >0){
			for (BmsResource bmsResource : bmsResourceList) {
				delResourcetList(bmsResource.getId());
			}
		}
		bmsResourceDao.del(id);
	}

	@Override
	public Map<String, Object> findRoleForUser(BmsUser bmsUser) throws Exception {
		Map<String, Object> resultMap = new HashMap<>();
		FindRequestEntity findReq = new FindRequestEntity();
		findReq.addWhere("type", WhereEnum.EQ, BmsRoleTypeEnum.Public_role.getKey());
		List<BmsRole> bmsRoleList = find(findReq);
		if(BmsUserTypeEnum.Scenic_area_administrator.getKey() == bmsUser.getType()){//景区用户
			findReq = new FindRequestEntity();
			findReq.addWhere("type", WhereEnum.EQ, BmsRoleTypeEnum.Scenic_role.getKey());
			bmsRoleList.addAll(find(findReq));
		}else if (BmsUserTypeEnum.Platform_user.getKey() == bmsUser.getType()) {//平台用户
			findReq = new FindRequestEntity();
			findReq.addWhere("type", WhereEnum.EQ, BmsRoleTypeEnum.Platform_role.getKey());
			bmsRoleList.addAll(find(findReq));
		}
		resultMap.put("bmsRoleList", bmsRoleList);
		return resultMap;
	}
}
